<?php

/**
 * Created by PhpStorm.
 * User: yutongfu
 * Date: 2019/7/6
 * Time: 11:03 AM
 */

class CacheRedis
{
    //三私一公
    //定义一个静态的私变量
    static private $_instance = null;
    private $redis = null;
    private $redis_prefix = '';

    //私有的构造方法
    private final function __construct()
    {
        //实例化
        $this->redis = new \Redis();
        $this->redis->connect('127.0.0.1', '6379');
        $this->redis->auth('');
        //$this->redis_prefix = (defined('REDIS_PREFIX') && REDIS_PREFIX) ? REDIS_PREFIX : '';
        $this->redis->select(0);
    }

    //私有的克隆方法
    private function __clone()
    {

    }

    //公有的静态方法
    static public function getInstance()
    {
        if (!(self::$_instance instanceof self)) {
            self::$_instance = new CacheRedis();
        }
        return self::$_instance;
    }

    /**
     * redis前缀
     * @param $name
     * @return string
     */
    private function getRedisKey($name)
    {
        $name = $this->redis_prefix . $name;
        return $name;
    }

    /**
     * 判断缓存
     * @access public
     * @param string $name 缓存变量名
     * @return bool
     */
    public function has($name)
    {
        $key = $this->getRedisKey($name);
        return $this->redis->get($key) ? true : false;
    }

    /**
     * 写入缓存
     * @access public
     * @param string $name 缓存变量名
     * @param mixed $value 存储数据
     * @param integer $expire 有效时间（秒）
     * @return boolean
     */
    public function set($name, $value, $expire = null)
    {
        $key = $this->getRedisKey($name);
        //对数组/对象数据进行缓存处理，保证数据完整性
        $value = (is_object($value) || is_array($value)) ? json_encode($value) : $value;
        if (is_int($expire) && $expire) {
            $result = $this->redis->setex($key, $expire, $value);
        } else {
            $result = $this->redis->set($key, $value);
        }
        return $result;
    }

    /**
     * 读取缓存
     * @access public
     * @param string $name 缓存变量名
     * @param mixed $default 默认值
     * @return mixed
     */
    public function get($name, $default = false)
    {
        $key = $this->getRedisKey($name);
        return $this->redis->get($key);
    }

    /**
     * 读取缓存
     * @param $name
     * @return array
     */
    public function mGet($name)
    {
        return $this->redis->mGet($name);
    }

    /**
     * 删除缓存
     * @param $name
     * @return bool|int
     */
    public function del($name)
    {
        $key = $this->getRedisKey($name);
        if ($this->redis->get($key)) {
            return $this->redis->del($key);
        } else {
            return true;
        }
    }

    /**
     * 模糊查找功能,支持*号以及?号(匹配一个字符)
     * @param $name
     * @return array
     */
    public function keys($name)
    {
        $key = $this->getRedisKey($name);
        return $this->redis->keys($key);
    }

    /**
     * 自增缓存（针对数值缓存）
     * @access public
     * @param string $name 缓存变量名
     * @param int $step 步长
     * @return false|int
     */
    public function inc($name, $step = 1)
    {
        $key = $this->getRedisKey($name);
        return $this->redis->incrby($key, $step);
    }

    /**
     * 自减缓存（针对数值缓存）
     * @access public
     * @param string $name 缓存变量名
     * @param int $step 步长
     * @return false|int
     */
    public function dec($name, $step = 1)
    {
        $key = $this->getRedisKey($name);
        return $this->redis->decrby($key, $step);
    }

    /*
     * 存取hash表的数据
     * @access public
     * @param string    $hash hash名称
     * @param string    $name 缓存变量名
     * @param mixed     $value  存储数据
     * @return boolean
     */
    public function hset($hash, $name, $value)
    {
        $key = $this->getRedisKey($hash);
        return $this->redis->hSet($key, $name, $value);
    }

    /*
     * 读取hash表的数据
     * @access public
     * @param string $hash hash名称
     * @param string $name 缓存变量名
     * @param mixed  $default 默认值
     * @return mixed
     */
    public function hget($hash, $name, $default = false)
    {
        $key = $this->getRedisKey($hash);
        $value = $this->redis->hGet($key, $name);
        if (is_null($value)) {
            return $default;
        }
        $jsonData = json_decode($value, true);
        // 检测是否为JSON数据 true 返回JSON解析数组, false返回源数据
        return (null === $jsonData) ? $value : $jsonData;
    }

    /**
     * 判断hash中是否存在缓存变量
     * @access public
     * @param string $hash hash名称
     * @param string $name 缓存变量名
     * @return bool
     */
    public function hexists($hash, $name)
    {
        $key = $this->getRedisKey($hash);
        return $this->redis->hExists($key, $name);
    }

    /**
     * 返回hash表中的所有key
     * @access public
     * @param string $hash hash名称
     * @return mixed
     */
    public function hkeys($hash)
    {
        $key = $this->getRedisKey($hash);
        return $this->redis->hKeys($key);
    }

    /**
     * 返回hash表中的所有val
     * @access public
     * @param string $hash hash名称
     * @return mixed
     */
    public function hvals($hash)
    {
        $key = $this->getRedisKey($hash);
        return $this->redis->hVals($key);
    }

    /**
     * 返回hash表元素个数
     * @access public
     * @param string $hash hash名称
     * @return mixed
     */
    public function hlen($hash)
    {
        $key = $this->getRedisKey($hash);
        return $this->redis->hLen($key);
    }

    /**
     * 返回整个hash表元素
     * @access public
     * @param string $hash hash名称
     * @return mixed
     */
    public function hgetall($hash)
    {
        $key = $this->getRedisKey($hash);
        return $this->redis->hGetAll($key);
    }

    /**
     * 删除缓存
     * @access public
     * @param string $name 缓存变量名
     * @return boolean
     */
    public function rm($name)
    {
        $key = $this->getRedisKey($name);
        return $this->redis->delete($key);
    }

    /**
     * 清除缓存
     * @access public
     * @param string $tag 标签名
     * @return boolean
     */
    public function clear($tag = null)
    {
        if ($tag) {
            // 指定标签清除
            $names = explode(',', $tag);
            foreach ($names as $name) {
                $this->rm($name);
            }
            return true;
        }
        return $this->redis->flushDB();
    }

    /**
     * 计数增加
     *
     * @param $name
     * @return int
     */
    public function incr($name){
        $key = $this->getRedisKey($name);
        return $this->redis->incr($key);
    }

    /**
     * 返回 list
     * @access public
     * @param string $hash list key
     * @param string $value list value
     * @return mixed
     */
    public function lpush($hash, $value)
    {
        $key = $this->getRedisKey($hash);
        return $this->redis->lPush($key, $value);
    }

    /**
     *  设置hash值
     * @access public
     * @param string $hash hash名称
     * @param array $value hash f-v
     * @return mixed
     */
    public function hmset($hash, $value)
    {
        $key = $this->getRedisKey($hash);
        return $this->redis->hMset($key, $value);
    }

    /**
     *  hash range
     * @access public
     * @param string $hash hash名称
     * @return array
     */
    public function lrange($hash, $first, $last)
    {
        $key = $this->getRedisKey($hash);
        return $this->redis->lrange($key, $first, $last);
    }

    /**
     *  list length
     * @access public
     * @param string list key
     * @return int
     */
    public function llen($hash)
    {
        $key = $this->getRedisKey($hash);
        return $this->redis->lLen($key);
    }

    /**
     * 删除缓存 hash,list
     * @param $name
     * @return bool|int
     */
    public function hdel($name)
    {
        $key = $this->getRedisKey($name);
        return $this->redis->del($key);
    }
}